package com.javafxboot.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class HttpClientUtil {


	private static RequestConfig requestConfig = RequestConfig.custom()
			.setSocketTimeout(30000).setConnectTimeout(30000)
			.setConnectionRequestTimeout(45000).build();

	private static HttpClientUtil instance = null;

	public HttpClientUtil() {
		
	}

	public static HttpClientUtil getInstance() {
		if (instance == null) {
			instance = new HttpClientUtil();
		}
		return instance;
	}

	/**
	 * 发送 post请求
	 * 
	 * @param httpUrl
	 *            地址
	 */
	public String sendHttpPost(String httpUrl) {
		/**
		 * 创建httpPost
		 */
		HttpPost httpPost = new HttpPost(httpUrl);
		httpPost.setConfig(requestConfig);
		return sendHttpPost(httpPost);
	}

	/**
	 * 发送 post请求
	 * 
	 * @param httpUrl
	 *            地址
	 * @param params
	 *            参数(格式:key1=value1&key2=value2)
	 */
	public static String sendHttpPost(String httpUrl, String params,String finalToken) {

		/**
		 * 创建httpPost
		 */
		HttpPost httpPost = new HttpPost(httpUrl);
		try {
			//String finalToken ="8CwJpSANQm7XgSH4zddkUzDHxKMfEDK7";
			httpPost.setHeader("Authorization", finalToken);

			// 设置参数
			httpPost.setConfig(requestConfig);
			StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/json");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			
		}
		return sendHttpPost(httpPost);
	}

	/**
	 * 发送 post请求
	 *
	 * @param httpUrl
	 *            地址
	 * @param params
	 *            参数(格式:key1=value1&key2=value2)
	 */
	public static String sendHttpPostText(String httpUrl, String params) {
		/**
		 * 创建httpPost
		 */
		HttpPost httpPost = new HttpPost(httpUrl);
		try {

			// 设置参数
			httpPost.setConfig(requestConfig);
			httpPost.setHeader("Referer", "https://epayment.7-11.com.tw/C2C/C2CWeb/C2CService.ashx");
			StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/x-www-form-urlencoded");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			
		}
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 post请求
	 *
	 * @param httpUrl
	 *            地址
	 * @param params
	 *            参数(格式:key1=value1&key2=value2)
	 */
	public static String sendHttpPostQj(String httpUrl, String params) {
		/**
		 * 创建httpPost
		 */
		HttpPost httpPost = new HttpPost(httpUrl);
		try {

			// 设置参数
			httpPost.setConfig(requestConfig);
			//httpPost.setHeader("Referer", "https://partner.shopeemobile.com/");
			StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/x-www-form-urlencoded");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			
		}
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 post请求
	 *
	 * @param httpUrl
	 *            地址
	 * @param params
	 *            参数(格式:key1=value1&key2=value2)
	 */
	public static String sendHttpPost(String httpUrl, String params) {

		/**
		 * 创建httpPost
		 */
		HttpPost httpPost = new HttpPost(httpUrl);
		try {

			// 设置参数
			httpPost.setConfig(requestConfig);
			StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/json");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			
		}
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 post请求
	 *
	 * @param httpUrl
	 *            地址
	 * @param params
	 *            参数(格式:key1=value1&key2=value2)
	 */
	public static String sendHttpPost711(String httpUrl, String params) {

		/**
		 * 创建httpPost
		 */
		HttpPost httpPost = new HttpPost(httpUrl);
		try {

			httpPost.setHeader("Referer", "https://epayment.7-11.com.tw/C2C/C2CWeb/C2C.aspx");
			// 设置参数
			httpPost.setConfig(requestConfig);
			StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/x-www-form-urlencoded");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			
		}
		return sendHttpPost(httpPost);
	}

	/**
	 * 发送 post请求
	 * 
	 * @param httpUrl
	 *            地址
	 * @param maps
	 *            参数
	 */
	public String sendHttpPost(String httpUrl, Map<String, String> maps) {
		HttpPost httpPost = new HttpPost(httpUrl);
		httpPost.setConfig(requestConfig);
		// 创建参数队列
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		for (String key : maps.keySet()) {
			nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
		}
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		} catch (Exception e) {


		}
		return sendHttpPost(httpPost);
	}

	/**
	 * 发送Post请求
	 * 
	 * @param httpPost
	 * @return
	 */
	private static String sendHttpPost(HttpPost httpPost) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			httpPost.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpPost);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
			
		} catch (Exception e) {
			
		} finally {
			
			try {
				if(response !=null){
					response.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				if(httpPost !=null){
					httpPost.releaseConnection();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				if(httpClient !=null){
					httpClient.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
		return responseContent;
	}

	/**
	 * 发送 get请求
	 * 
	 * @param httpUrl
	 */
	public String sendHttpGet(String httpUrl) {
		
		HttpGet httpGet = new HttpGet(httpUrl);
		httpGet.setConfig(requestConfig);
		return sendHttpGet(httpGet);
	}


	/**
	 * 发送Get请求
	 * 
	 * @param
	 * @return
	 */
	private String sendHttpGet(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
			httpGet.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
			
		} catch (Exception e) {
			
		} finally {
//			closeQuietly(response);
//			closeQuietly(httpClient);
			
			try {
				if(response !=null){
					response.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				if(httpGet !=null){
					httpGet.releaseConnection();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				if(httpClient !=null){
					httpClient.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
		return responseContent;
	}

	
	/**
	 * 释放资源
	 *
	 * <p>
	 * TODO 方法功能描述
	 *
	 * @param response
	 *            void
	 */
	public static void closeQuietly(CloseableHttpResponse response) {
		if (response == null) {
			return;
		}
		HttpEntity entity = response.getEntity();
		try {
			// 关闭流
			if (entity != null && entity.isStreaming()) {
				InputStream instream = entity.getContent();
				if (instream != null) {
					instream.close();
				}
			}
			// 释放链接
			response.close();
		} catch (IOException e) {
			
		}
	}

	/**
	 * 释放资源
	 *
	 * <p>
	 * 关闭
	 *
	 * @param httpClient
	 * @return void
	 */
	public static void closeQuietly(CloseableHttpClient httpClient) {
		if (httpClient == null) {
			return;
		}
		try {
			httpClient.close();
		} catch (IOException e) {
			
		}
	}

	/**
	 *
	 * @param url
	 * @param param
	 */
	public static HttpResponse downLoadFile(String url, Map<String,String> param){
		// 生成一个httpclient对象
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpGet httpget = new HttpGet(url);
		try {
			HttpResponse response = httpclient.execute(httpget);
			return response;
		} catch (Exception e ){
           e.printStackTrace();
		}
		return  null;
	}



    /**
     * @param urlPath 下载路径
     * @param urlPath otcsticket
     * @return 返回下载文件
     */
    public byte[] downloadFile(String urlPath, String otcsticket) {
        BufferedInputStream bin = null;
        ByteArrayOutputStream bos = null;
        try {
            // 统一资源
            URL url = new URL(urlPath);
            // 连接类的父类，抽象类
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            // 设定请求的方法，默认是GET
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoInput(true);
            //上传参数，需要打开output流，将参数写到流中提交
            urlConnection.setDoOutput(true);
            // 忽略缓存
            urlConnection.setUseCaches(false);
            urlConnection.setRequestProperty("otcsticket", otcsticket);
            urlConnection.setRequestProperty("Accept", "*/*");
            urlConnection.setRequestProperty("Content-Type", "application/octet-stream");
            // 维持长连接
            urlConnection.setRequestProperty("Connection", "Keep-Alive");
            // 设置字符编码
            urlConnection.setRequestProperty("Charset", "UTF-8");
            // 打开到此 URL 引用的资源的通信链接（如果尚未建立这样的连接）。
            urlConnection.connect();
            // 文件大小
            int fileLength = urlConnection.getContentLength();

            
            bin = new BufferedInputStream(urlConnection.getInputStream());
            int len = 0;
            byte[] buffer = new byte[1024];
            bos = new ByteArrayOutputStream();
            while ((len = bin.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
        } catch (MalformedURLException e) {
            
        } catch (IOException e) {

        } finally {
            try {
                if (bin != null) {
                    bin.close();
                }
            } catch (IOException e) {
               
            }
        }

        if(bos !=null ){
			return bos.toByteArray();
		}
		return null;

    }

    public static void main(String[] args) throws Exception {
	}


	

	static BASE64Encoder encoder = new BASE64Encoder();
	static BASE64Decoder decoder = new BASE64Decoder();


	/**
	 *  将PDF转换成base64编码
	 *  1.使用BufferedInputStream和FileInputStream从File指定的文件中读取内容；
	 *  2.然后建立写入到ByteArrayOutputStream底层输出流对象的缓冲输出流BufferedOutputStream
	 *  3.底层输出流转换成字节数组，然后由BASE64Encoder的对象对流进行编码
	 * */
	static String getPDFBinary(File file) {
		FileInputStream fin =null;
		BufferedInputStream bin =null;
		ByteArrayOutputStream baos = null;
		BufferedOutputStream bout =null;
		try {
			//建立读取文件的文件输出流
			fin = new FileInputStream(file);
			//在文件输出流上安装节点流（更大效率读取）
			bin = new BufferedInputStream(fin);
			// 创建一个新的 byte 数组输出流，它具有指定大小的缓冲区容量
			baos = new ByteArrayOutputStream();
			//创建一个新的缓冲输出流，以将数据写入指定的底层输出流
			bout = new BufferedOutputStream(baos);
			byte[] buffer = new byte[1024];
			int len = bin.read(buffer);
			while(len != -1){
				bout.write(buffer, 0, len);
				len = bin.read(buffer);
			}
			//刷新此输出流并强制写出所有缓冲的输出字节，必须这行代码，否则有可能有问题
			bout.flush();
			byte[] bytes = baos.toByteArray();
			//sun公司的API
			return encoder.encodeBuffer(bytes).trim();
			//apache公司的API

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				if(fin!=null ){
					fin.close();
				}
				if(bin!=null ){
					bin.close();
				}
				if(bout!=null ){
					bout.close();
				}
				//关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用，而不会产生任何 IOException
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 将base64编码转换成PDF
	 * @param base64sString
	 * 1.使用BASE64Decoder对编码的字符串解码成字节数组
	 *  2.使用底层输入流ByteArrayInputStream对象从字节数组中获取数据；
	 *  3.建立从底层输入流中读取数据的BufferedInputStream缓冲输出流对象；
	 *  4.使用BufferedOutputStream和FileOutputSteam输出数据到指定的文件中
	 */
	/*static void base64StringToPDF(String base64sString){
		BufferedInputStream bin = null;
		FileOutputStream fout = null;
		BufferedOutputStream bout = null;
		try {
			//将base64编码的字符串解码成字节数组
			byte[] bytes = decoder.decodeBuffer(base64sString);
			//apache公司的API
			ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
			//创建从底层输入流中读取数据的缓冲输入流对象
			bin = new BufferedInputStream(bais);
			//指定输出的文件
			File file = new File("F://test.pdf");
			//创建到指定文件的输出流
			fout  = new FileOutputStream(file);
			//为文件输出流对接缓冲输出流对象
			bout = new BufferedOutputStream(fout);

			byte[] buffers = new byte[1024];
			int len = bin.read(buffers);
			while(len != -1){
				bout.write(buffers, 0, len);
				len = bin.read(buffers);
			}
			//刷新此输出流并强制写出所有缓冲的输出字节，必须这行代码，否则有可能有问题
			bout.flush();

		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {

				if(bin!=null ){
					bin.close();
				}
				if(fout!=null ){
					fout.close();
				}
				if(bout!=null ){
					bout.close();
				}


			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}*/


}